package com.myproject.myblogserver.controller;

import org.springframework.web.bind.annotation.RequestMapping;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.myproject.myblogserver.contant.CommonConstants;
import com.myproject.myblogserver.dto.PageResultDto;
import com.myproject.myblogserver.dto.comment.CommentAddDto;
import com.myproject.myblogserver.dto.comment.CommentDisplayDto;
import com.myproject.myblogserver.dto.comment.CommentPreviewDto;
import com.myproject.myblogserver.dto.comment.CommentQueryDto;
import com.myproject.myblogserver.dto.reply.ReplyDisplayDto;
import com.myproject.myblogserver.entity.Blog;
import com.myproject.myblogserver.entity.User;
import com.myproject.myblogserver.entity.BlogComment;
import com.myproject.myblogserver.entity.CommentLike;
import com.myproject.myblogserver.entity.CommentReply;
import com.myproject.myblogserver.entity.CommentReplyLike;
import com.myproject.myblogserver.service.IBlogCommentService;
import com.myproject.myblogserver.service.IBlogService;
import com.myproject.myblogserver.service.ICommentLikeService;
import com.myproject.myblogserver.service.ICommentReplyLikeService;
import com.myproject.myblogserver.service.ICommentReplyService;
import com.myproject.myblogserver.service.IUserService;
import com.myproject.myblogserver.utils.JwtUtil;

/**
 * <p>
 * 博客评论表 前端控制器
 * </p>
 *
 * @author jiangweike
 * @since 2025-02-16
 */
@Controller
@RequestMapping("/blogComment")
public class BlogCommentController {

	@Autowired
	private IBlogCommentService blogCommentService;

	@Autowired
	private IUserService userService;

	@Autowired
	private ICommentLikeService commentLikeService;

	@Autowired
	private ICommentReplyService commentReplyService;

	@Autowired
	private IBlogService blogService;

	@Autowired
	private ICommentReplyLikeService commentReplyLikeService;

	@PostMapping("/add")
	public ResponseEntity<?> add(@RequestBody CommentAddDto commentAddDto,
			@RequestHeader("Authorization") String authHeader) {
		try {
			var userId = JwtUtil.extractUserIdFromAuthHeader(authHeader);
			var blogComment = new BlogComment();
			blogComment.setBlogId(commentAddDto.getBlogId());
			blogComment.setUserId(userId);
			blogComment.setContent(commentAddDto.getCommentContent());
			blogCommentService.save(blogComment);
			return ResponseEntity.ok("评论成功！");
		} catch (Exception e) {
			return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("评论失败！");
		}
	}

	@PostMapping("/delete/{blogCommentId}")
	public ResponseEntity<?> delete(@PathVariable Long blogCommentId,
			@RequestHeader("Authorization") String authHeader) {
		try {
			var userId = JwtUtil.extractUserIdFromAuthHeader(authHeader);
			var blogComment = blogCommentService.lambdaQuery()
					.eq(BlogComment::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.eq(BlogComment::getId, blogCommentId)
					.select(BlogComment::getUserId)
					.one();

			// 添加非空检查并使用equals比较Long
			if (blogComment != null && userId.equals(blogComment.getUserId())) {
				blogCommentService.lambdaUpdate()
						.set(BlogComment::getIsDeleted, CommonConstants.DELETED_STATUS_YES)
						.set(BlogComment::getUpdatedAt, LocalDateTime.now())
						.eq(BlogComment::getId, blogCommentId)
						.update();
			} else {
				throw new RuntimeException("无权删除或评论不存在");
			}
			return ResponseEntity.ok("删除评论成功！");
		} catch (Exception e) {
			return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("删除评论失败！");
		}
	}

	@GetMapping("get/{pageIndex}")
	public ResponseEntity<?> get(@PathVariable Integer pageIndex,
			@RequestHeader("Authorization") String authHeader) {
		try {
			var userId = JwtUtil.extractUserIdFromAuthHeader(authHeader);
			var blogComments = blogCommentService.lambdaQuery()
					.eq(BlogComment::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.eq(BlogComment::getUserId, userId)
					.select(BlogComment::getId, BlogComment::getContent, BlogComment::getCreatedAt,
							BlogComment::getBlogId)
					.list();

			var blogIds = blogComments.stream().map(BlogComment::getBlogId).toList();
			var blogPage = blogService.lambdaQuery()
					.eq(Blog::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.in(!blogIds.isEmpty(), Blog::getId, blogIds)
					.select(Blog::getId, Blog::getTitle, Blog::getSummary)
					.page(new Page<>(pageIndex, CommonConstants.DEFAULT_PAGE_SIZE));

			var commentPreviewList = new ArrayList<CommentPreviewDto>();

			// 创建博客ID到博客信息的映射
			var blogMap = blogPage.getRecords().stream()
					.collect(java.util.stream.Collectors.toMap(Blog::getId, blog -> blog));

			// 组装CommentPreviewDto列表
			for (var comment : blogComments) {
				var blog = blogMap.get(comment.getBlogId());
				if (blog != null) {
					var preview = new CommentPreviewDto();
					preview.setId(blog.getId());
					preview.setTitle(blog.getTitle());
					preview.setSummary(blog.getSummary());
					preview.setComment(comment.getContent());
					preview.setCreatedAt(comment.getCreatedAt());
					commentPreviewList.add(preview);
				}
			}

			// 构建分页结果
			var pageResult = new PageResultDto<CommentPreviewDto>();
			pageResult.setContent(commentPreviewList);
			pageResult.setTotalPages(blogPage.getPages());

			return ResponseEntity.ok(pageResult);
		} catch (Exception e) {
			return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("获取评论列表失败！");
		}
	}

	@PostMapping("/query")
	public ResponseEntity<?> query(@RequestBody CommentQueryDto commentQueryDto,
			@RequestHeader("Authorization") String authHeader) {
		try {
			var userId = JwtUtil.extractUserIdFromAuthHeader(authHeader);
			var pageIndex = commentQueryDto.getPageIndex();
			var blogId = commentQueryDto.getBlogId();

			// 分页查询评论
			var commentPage = blogCommentService.lambdaQuery()
					.eq(BlogComment::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.eq(BlogComment::getBlogId, blogId)
					.select(BlogComment::getUserId, BlogComment::getId, BlogComment::getCreatedAt,
							BlogComment::getContent)
					.page(new Page<>(pageIndex, CommonConstants.DEFAULT_PAGE_SIZE));

			var comments = commentPage.getRecords();
			var commentIds = comments.stream().map(BlogComment::getId).collect(Collectors.toList());
			var commentUserIds = comments.stream().map(BlogComment::getUserId).collect(Collectors.toList());

			// 查询评论用户信息
			var commentUsers = userService.lambdaQuery()
					.eq(User::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.in(!commentUserIds.isEmpty(), User::getId, commentUserIds)
					.select(User::getId, User::getName, User::getAvatar)
					.list();

			// 查询所有相关回复
			var replys = commentReplyService.lambdaQuery()
					.eq(CommentReply::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.in(!commentIds.isEmpty(), CommentReply::getCommentId, commentIds)
					.select(CommentReply::getId, CommentReply::getUserId, CommentReply::getCommentId,CommentReply::getContent,
							CommentReply::getCreatedAt, CommentReply::getParentUserId)
					.list();

			var replyIds = replys.stream().map(CommentReply::getId).collect(Collectors.toList());
			var replyUserIds = replys.stream().map(CommentReply::getUserId).collect(Collectors.toList());
			var parentUserIds = replys.stream().map(CommentReply::getParentUserId).collect(Collectors.toList());

			// 查询回复相关用户信息
			var replyUsers = userService.lambdaQuery()
					.eq(User::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.in(!replyUserIds.isEmpty(), User::getId, replyUserIds)
					.select(User::getId, User::getName, User::getAvatar)
					.list();

			var parentUsers = userService.lambdaQuery()
					.eq(User::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.in(!parentUserIds.isEmpty(), User::getId, parentUserIds)
					.select(User::getId, User::getName)
					.list();

			// 创建用户映射
			Map<Long, User> commentUserMap = commentUsers.stream()
					.collect(Collectors.toMap(User::getId, u -> u));
			Map<Long, User> replyUserMap = replyUsers.stream()
					.collect(Collectors.toMap(User::getId, u -> u));
			Map<Long, User> parentUserMap = parentUsers.stream()
					.collect(Collectors.toMap(User::getId, u -> u));

			// 查询评论点赞信息
			Map<Long, Long> commentLikeCounts = commentLikeService.lambdaQuery()
					.in(!commentIds.isEmpty(), CommentLike::getCommentId, commentIds)
					.eq(CommentLike::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.groupBy(CommentLike::getCommentId)
					.select(CommentLike::getCommentId, CommentLike::getCount)
					.list()
					.stream()
					.collect(Collectors.toMap(CommentLike::getCommentId, CommentLike::getCount));

			Map<Long, Boolean> commentLikedStatus = commentLikeService.lambdaQuery()
					.in(!commentIds.isEmpty(), CommentLike::getCommentId, commentIds)
					.eq(CommentLike::getUserId, userId)
					.eq(CommentLike::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.select(CommentLike::getCommentId)
					.list()
					.stream()
					.collect(Collectors.toMap(CommentLike::getCommentId, cl -> true));

			// 查询回复点赞信息
			Map<Long, Long> replyLikeCounts = commentReplyLikeService.lambdaQuery()
					.in(!replyIds.isEmpty(), CommentReplyLike::getReplyId, replyIds)
					.eq(CommentReplyLike::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.groupBy(CommentReplyLike::getReplyId)
					.select(CommentReplyLike::getReplyId, CommentReplyLike::getCount)
					.list()
					.stream()
					.collect(Collectors.toMap(CommentReplyLike::getReplyId, CommentReplyLike::getCount));

			Map<Long, Boolean> replyLikedStatus = commentReplyLikeService.lambdaQuery()
					.in(!replyIds.isEmpty(), CommentReplyLike::getReplyId, replyIds)
					.eq(CommentReplyLike::getUserId, userId)
					.eq(CommentReplyLike::getIsDeleted, CommonConstants.DELETED_STATUS_NO)
					.select(CommentReplyLike::getReplyId)
					.list()
					.stream()
					.collect(Collectors.toMap(CommentReplyLike::getReplyId, rl -> true));

			// 构建回复分组
			Map<Long, List<CommentReply>> replyMap = replys.stream()
					.collect(Collectors.groupingBy(CommentReply::getCommentId));

			// 转换评论DTO
			List<CommentDisplayDto> commentDtos = comments.stream().map(comment -> {
				User user = commentUserMap.get(comment.getUserId());
				CommentDisplayDto dto = new CommentDisplayDto();
				dto.setCommentId(comment.getId());
				dto.setUserId(comment.getUserId());
				dto.setName(user.getName());
				dto.setAvatar(user.getAvatar());
				dto.setContent(comment.getContent());

				dto.setDateTime(comment.getCreatedAt());

				// 设置评论点赞信息
				dto.setLikeCount(commentLikeCounts.getOrDefault(comment.getId(), 0L));
				dto.setIsLike(commentLikedStatus.getOrDefault(comment.getId(), false));

				// 处理回复
				List<CommentReply> replies = replyMap.getOrDefault(comment.getId(), Collections.emptyList());
				List<ReplyDisplayDto> replyDtos = replies.stream().map(reply -> {
					User replyUser = replyUserMap.get(reply.getUserId());
					User parentUser = parentUserMap.get(reply.getParentUserId());

					ReplyDisplayDto replyDto = new ReplyDisplayDto();
					replyDto.setReplyId(reply.getId());
					replyDto.setUserId(reply.getUserId());
					replyDto.setUserName(replyUser.getName());
					replyDto.setUserAvatar(replyUser.getAvatar());
					replyDto.setReplyUserId(reply.getParentUserId());
					if (parentUser != null)
						replyDto.setReplyUserName(parentUser.getName());
					replyDto.setContent(reply.getContent());
					replyDto.setDateTime(reply.getCreatedAt());

					// 设置回复点赞信息
					replyDto.setLikeCount(replyLikeCounts.getOrDefault(reply.getId(), 0L));
					replyDto.setIsLike(replyLikedStatus.getOrDefault(reply.getId(), false));

					return replyDto;
				}).collect(Collectors.toList());

				dto.setReplys(new ArrayList<>(replyDtos));
				return dto;
			}).collect(Collectors.toList());

			// 构建分页结果
			var result = new PageResultDto<CommentDisplayDto>();
			result.setContent(commentDtos);
			result.setTotalPages(commentPage.getPages());

			return ResponseEntity.ok(result);
		} catch (Exception e) {
			return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("获取评论失败：" + e.getMessage());
		}
	}
}
